package biz

import (
	"context"
	"errors"
)

// BrandRepo 品牌仓储接口，定义品牌相关的数据操作方法
// 包括创建、更新、查询、删除、唯一性校验、引用校验等
type BrandRepo interface {
	Create(ctx context.Context, b *Brand) (*Brand, error)                // 创建品牌
	Update(ctx context.Context, b *Brand) (*Brand, error)                // 更新品牌
	Get(ctx context.Context, id int64) (*Brand, error)                   // 查询品牌详情
	List(ctx context.Context, page, pageSize int) ([]*Brand, int, error) // 分页查询品牌列表
	Delete(ctx context.Context, id int64) error                          // 删除品牌
	NameExists(ctx context.Context, name string) bool                    // 校验品牌名唯一性
	HasProduct(ctx context.Context, brandId int64) bool                  // 校验品牌是否被商品引用
}

// BrandUsecase 品牌用例层，封装品牌相关业务逻辑
type BrandUsecase struct {
	repo BrandRepo
}

// NewBrandUsecase 创建品牌用例实例
func NewBrandUsecase(repo BrandRepo) *BrandUsecase {
	return &BrandUsecase{repo: repo}
}

// Create 创建品牌
func (uc *BrandUsecase) Create(ctx context.Context, b *Brand) (*Brand, error) {
	// 数据验证
	if err := uc.validateBrand(b); err != nil {
		return nil, err
	}

	// 检查品牌名唯一性
	if uc.repo.NameExists(ctx, b.Name) {
		return nil, errors.New("品牌名称已存在")
	}

	return uc.repo.Create(ctx, b)
}

// Update 更新品牌
func (uc *BrandUsecase) Update(ctx context.Context, b *Brand) (*Brand, error) {
	// 数据验证
	if err := uc.validateBrand(b); err != nil {
		return nil, err
	}

	// 检查品牌是否存在
	existing, err := uc.repo.Get(ctx, b.ID)
	if err != nil {
		return nil, errors.New("品牌不存在")
	}

	// 如果名称变更，检查唯一性
	if existing.Name != b.Name && uc.repo.NameExists(ctx, b.Name) {
		return nil, errors.New("品牌名称已存在")
	}

	return uc.repo.Update(ctx, b)
}

// Get 查询品牌详情
func (uc *BrandUsecase) Get(ctx context.Context, id int64) (*Brand, error) {
	if id <= 0 {
		return nil, errors.New("品牌ID无效")
	}
	return uc.repo.Get(ctx, id)
}

// List 分页查询品牌列表
func (uc *BrandUsecase) List(ctx context.Context, page, pageSize int) ([]*Brand, int, error) {
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 || pageSize > 100 {
		pageSize = 20
	}
	return uc.repo.List(ctx, page, pageSize)
}

// Delete 删除品牌
func (uc *BrandUsecase) Delete(ctx context.Context, id int64) error {
	if id <= 0 {
		return errors.New("品牌ID无效")
	}

	// 检查品牌是否存在
	_, err := uc.repo.Get(ctx, id)
	if err != nil {
		return errors.New("品牌不存在")
	}

	// 检查是否被商品引用
	if uc.repo.HasProduct(ctx, id) {
		return errors.New("品牌正在被商品使用，无法删除")
	}

	return uc.repo.Delete(ctx, id)
}

// validateBrand 验证品牌数据
func (uc *BrandUsecase) validateBrand(b *Brand) error {
	if b.Name == "" {
		return errors.New("品牌名称不能为空")
	}
	if len(b.Name) > 50 {
		return errors.New("品牌名称长度不能超过50个字符")
	}
	return nil
}

// NameExists 校验品牌名唯一性
func (uc *BrandUsecase) NameExists(ctx context.Context, name string) bool {
	return uc.repo.NameExists(ctx, name)
}

// HasProduct 校验品牌是否被商品引用
func (uc *BrandUsecase) HasProduct(ctx context.Context, brandId int64) bool {
	return uc.repo.HasProduct(ctx, brandId)
}
